package cn.tedu.v3_1;

import java.io.*;
import java.net.*;
import java.util.*;

/**
 *  多人聊天室 Version  3.1
 *  【优化版本】功能：客户端与服务器端可以双向沟通
 *  优化①：导入包开始优化，通配符
 *  优化②：将动态的数据全部封装到类上，代码更加易用[失败]
 *  优化③：将读入和写出   操作定于---构造器 | 功能
 *      构造器主要用于对象的初始化，Client对象初始化：添加了IP和端口号
 *                                             流创建添加
 *      优点：1.减少代码重复和复杂度
 *           2.代码结构更加清晰
 *           3.客户端创建之初：明确具备读写
 *      构造器：读写定义
 *      start方法：保留读写功能
 *
 *  问题1：标准IO流置空，线程中使用BufferedRead 无法到达【作用域不够】
 *   流置空的问题更适合在短期，简单场景中使用，不一定保证对象正确释放
 *   有可能报出null，实际软件开发中使用javaOOP封装思路替换置空方式
 *   置空流  方式      升级    javaOOP 封装方式：流私有化属性：流，IP，socket
 *
 *   好处：①数据保护：本类不可访问，确保其他类无法直接访问！
 *        ②易用性和安全性：置空操作--目的：赋值，关闭，紧邻try上！
 *                       私有化属性-->便于使用，流正确关闭！
 */
public class Client {
    //优化  ②：动态数据全部私有化属性到类上---方便修改
    private static final String HOST="192.168.71.139";
    private static final Integer PORT=9908;

    private Socket socket;
    private String ip;
  //1.置空流升级为javaOOp中的封装-->私有化属性：本类任意地方都可以使用
    private PrintWriter pw;
    private BufferedReader br;

    public Client(){

        try {
            //私有化socket---拨通服务器电话---返回socket【不能省】
            socket =new Socket(HOST,PORT);
            ip=socket.getInetAddress().getHostAddress();

            br=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF8"));
            pw=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF8")),true);
        }catch (SocketException e) {
            System.out.println("连接被重置");
        }catch (UnknownHostException e) {  //用户地址出问题了（异常）
            System.out.println("IP地址有问题，请询问服务器端！");
        }
        catch (IOException e) { //IO异常：连接失效，客户端主动退出了
            System.out.println("客户端主动退出了：断开连接");
        }
    }

    public void start() {
        try {


            new Thread(()->{
                try {
                    String message;
                    while((message=br.readLine())!=null){
                        System.out.println("服务器端说："+message);
                        System.out.println("客户端请输入：");
                    }
                } catch (IOException e) {
                    System.out.println("服务端发来的消息断开了~");
                }
            }).start();

            Scanner input=new Scanner(System.in);
            while(true){
                System.out.println("客户端请输入：");
                String say=input.nextLine();
                pw.println("客户端说："+say);
            }

        } finally {
            if (pw!=null)
                pw.close();
            if (br!=null)
                try {
                    br.close();
                } catch (IOException e) {
                    System.out.println("服务器端链接失败~~");
                }
            if (socket!=null&&!socket.isClosed()){
                System.out.println("客户端关闭成功!");
                try {
                    socket.close();
                } catch (IOException e) {
                    System.out.println("客户端关闭失败~");
                }
            }
        }
    }

    public static void main(String[] args){
        new Client().start();
    }
}
